package backend.category.manager;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;

import backend.cms.manager.CmsManager;

import core.category.model.Category;
import core.category.model.CategoryType;
import core.cms.model.Block;
import core.product.model.Product;
import core.util.HibernateCoreUtil;

public class CategoryManager extends HibernateCoreUtil
{
	public void save(Category c)
	{
		Session session = HibernateCoreUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();
		session.saveOrUpdate(c);
		session.getTransaction().commit();
		
	}
	public Category getCategoryByName(String name)
	{
		Category c = null ;
		Session session = HibernateCoreUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();
		List<Category> cLst =  session.createQuery("from Category where name = '"+name+"'").list();
		if(cLst.size() > 0)
		{
			c = cLst.get(0);
		}
		session.getTransaction().commit();
		return c;
	}
	public List<Category> getCategoryByType(CategoryType ct)
	{
		Session session = HibernateCoreUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();
		List<Category> continents = (List<Category>) session.createQuery("from Category where categoryType=:ct").setEntity("ct", ct).list();
		session.getTransaction().commit();
		return continents;
	}
	public Map<Category,Integer> getSubCategoryListCont(Category parent)
	{
		Map<Category,Integer> subCategory = new HashMap<Category,Integer>();
		Iterator<Category> subCate = this.getCategoryList(parent).iterator();
		while(subCate.hasNext())
		{
			Category c = subCate.next() ;
			int productCount = 0 ;
			if(c.getProducts() != null)
			{
				productCount = c.getProducts().size();
			}
			subCategory.put(c, productCount);
		}
		return subCategory ;
	}
	public List<Category> getCategoryList(Category parent)
	{
		Session session = HibernateCoreUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();
		List <Category> cate = session.createQuery("from Category c where c.parent=:p").setEntity("p",parent).list();	
		session.getTransaction().commit();
		return cate ;	
	}
	public List<Category> getSubCategoryByType(Category parent,CategoryType ct)
	{
		Session session = HibernateCoreUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();
		List <Category> cate = session.createQuery("from Category c where c.parent=:p and c.categoryType=:ct").setEntity("ct", ct).setEntity("p",parent).list();	
		session.getTransaction().commit();
		return cate ;	
	}
	public List<CategoryType> getAllCategoryType()
	{
		Session session = HibernateCoreUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();
		List <CategoryType> cateT = session.createQuery("from CategoryType where type != \'world\'").list();	
		session.getTransaction().commit();
		return cateT ;
		
	}
	public List<CategoryType> getValidCategoryType(Category c)
	{
		Session session = HibernateCoreUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();
		String qry = new String("from CategoryType where type not in ('world'");
		if(c.getCategoryType().getType().equals("continent"))
		{
			qry = qry + "," +"'continent')";
		}
		else if(c.getCategoryType().getType().equals("country"))
		{
			qry = qry + "," +"'continent'" + "," + "'country')";
		}
		else if(c.getCategoryType().getType().equals("state"))
		{
			qry = qry + "," +"'continent'" + "," + "'country'" + "," + "'state')";
		}
		else if(c.getCategoryType().getType().equals("region"))
		{
			qry = qry + "," +"'continent'" + "," + "'country'" + "," + "'state'" + "," + "'region')";
		}
		else if(c.getCategoryType().getType().equals("city"))
		{
			qry = qry + "," +"'continent'" + "," + "'country'" + "," + "'state'" + "," + "'region'" + "," + "'city')";
		}
		else
		{
			qry = qry + ")";
		}
		List <CategoryType> cateT = session.createQuery(qry).list();	
		session.getTransaction().commit();
		return cateT ;
	}
	public CategoryType getCategoryTypeByUUID(Long uuid)
	{
		Session session = HibernateCoreUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();
		CategoryType cateT = (CategoryType) session.get(CategoryType.class, uuid);
		session.getTransaction().commit();
		return cateT ;	
	}
	public CategoryType getCategoryTypeByName(String name)
	{
		CategoryType ct = null ;
		Session session = HibernateCoreUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();
		List <CategoryType> cateTs = session.createQuery("from CategoryType where type ='"+name+"'").list();
		if(cateTs.size() > 0)
		{
			ct = cateTs.get(0);
		}
		session.getTransaction().commit();
		return ct ;	
	}
	public List<Category> getSubCategoryByPath(String path)
	{
		Session session = HibernateCoreUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();
		List <Category> cateT = session.createQuery("from Category where path like '"+path+"%'").list();	
		session.getTransaction().commit();
		return cateT ;
	}
	public void massRemoveCategory(List<Category> categories)
	{
		List<Category> newCateies = new ArrayList<Category>();
		Iterator<Category> cateItr = categories.iterator();
		CmsManager cmsm = new CmsManager();
		while(cateItr.hasNext())
		{
			Category c = cateItr.next();
			Block b = c.getBlock();
			c.setBlock(null);
			c.setCategoryType(null);
			c.setParent(null);
			c.setProducts(null);
			this.save(c);
			if(b != null)
			{
				cmsm.deleteBlockContent(b);
			}
			newCateies.add(c);
		}
		Iterator<Category> freeItr = newCateies.iterator();
		while(freeItr.hasNext())
		{
			Category c2 = freeItr.next();
			this.removeCategory(c2);
		}
		
	}
	public void removeCategory(Category c)
	{
		Session session = HibernateCoreUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();
		session.delete(c);
		session.getTransaction().commit();
	}
	public Category getCategoryByUuid(Long uuid)
	{
		Category c = null ;
		Session session = HibernateCoreUtil.getSessionFactory().openSession();
		Transaction transaction = null;
		try 
		{
				transaction = session.beginTransaction();
				c = (Category) session.get(Category.class, uuid);
				transaction.commit();
		}
		catch (HibernateException e) 
		{
			// TODO: handle exception
			transaction.rollback();
			e.printStackTrace();
		}
		finally 
		{
			session.close();
		}
		return c ;
	}
	public void addProduct(Category c, Product p)
	{
		Session session = HibernateCoreUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();
		c.getProducts().add(p);
		session.saveOrUpdate(c);
		session.getTransaction().commit();
	}
	public void removeProduct(Category c, Product p)
	{
		Session session = HibernateCoreUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();
		c.getProducts().remove(p);
		session.saveOrUpdate(c);
		session.getTransaction().commit();
	}
}
